package org.se.exception;

/**
 * {@link BasicException} 对应的测试类
 *
 * @author wangMaoXiong
 * @version 1.0
 * @date 2022/1/26 15:15
 */
public class BasicExceptionTest {
    /**
     * daoFun 方法模拟 dao 层，持久化层的异常通常直接往外抛。
     * 运行时异常的方法上可以不加 throws 往外抛。
     *
     * @param age
     * @throws BasicException
     */
    public void daoFun(Integer age) {
        if (age == null || age <= 0) {
            throw new BasicException("[年龄不能为空或负数：" + age + "]");
        }
    }

    /**
     * serviceFun 方法模拟 service 层
     *
     * @param age
     * @throws RuntimeException
     */
    public void serviceFun(Integer age) {
        try {
            BasicExceptionTest test3 = new BasicExceptionTest();
            test3.daoFun(age);
        } catch (BasicException e) {
            //对于中间层继续往上抛异常时，需要注意将异常对象 e 也一并带上，因为它含有原始的堆栈信息
            //对于编译时异常，直接往外抛原始对象时，相当于自己没有处理，此时方法上面必须使用 throws 继续往外抛
            throw e;
            //如这种方式，相当于往外抛了两个异常对象，上层是 RuntimeException，下层是 BasicException
            //throw new RuntimeException(e.getMessage() + " - ", e);

            //比如如下这种方式，继续抛 RuntimeException 异常时，只是简单的获取了 BasicException 的异常消息，而它的堆栈信息已经没有了
            //没有了 BasicException 的原始堆栈信息，也就无法定位最开始抛出异常的地方了
            //throw new RuntimeException(e.getMessage());
        }
    }

    /**
     * controllerFun 方法模拟控制层，控制层不宜再继续往外抛异常，而是应该转换为用户能简单理解的提示信息
     *
     * @param age
     * @return
     */
    public String controllerFun(Integer age) {
        try {
            BasicExceptionTest test3 = new BasicExceptionTest();
            test3.serviceFun(age);
        } catch (BasicException e) {
            /**
             * 实际开发中并不推荐使用 e.printStackTrace(); 并不仅仅是打印堆栈信息到控制台， 它不仅影响性能，而且还可能造成死锁
             * 推荐的是应该使用 slf4j 等日志框架将异常信息输出到日志文件中，这样才利于后期维护与排错
             * 可以参考：https://blog.csdn.net/qq_28929589/article/details/82495193
             */
            //org.se.exception.BasicException: [年龄不能为空或负数：-300]
            //at org.se.exception.BasicExceptionTest.daoFun(BasicExceptionTest.java:20)
            //at org.se.exception.BasicExceptionTest.serviceFun(BasicExceptionTest.java:33)
            //at org.se.exception.BasicExceptionTest.controllerFun(BasicExceptionTest.java:56)
            //at org.se.exception.BasicExceptionTest.main(BasicExceptionTest.java:75)

            e.printStackTrace();
            return "您的年龄输入不合理!";
        } catch (RuntimeException e) {
            e.printStackTrace();
            return "系统异常!";
        }
        return "success";
    }

    public static void main(String[] args) {
        Integer age = -300;
        BasicExceptionTest test3 = new BasicExceptionTest();
        String result = test3.controllerFun(age);
        //您的年龄输入不合理!
        System.out.println(result);
    }

}
